package oplog

import (
	"context"
	"devops-super/internal/model/mymodel"
	"devops-super/internal/service"
	"devops-super/utility/util/ipUtil"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/glog"
	"strings"
)

// OperationLog 操作日志写入
func (s *sOplog) OperationLog(r *ghttp.Request) {
	// get不记录日志
	method := strings.ToLower(r.Method)
	if method == "get" {
		return
	}
	userInfo, err := service.User().GetCurrentUser(r.GetCtx())
	if userInfo == nil {
		return
	}

	// 获取请求相关信息
	url := r.Request.URL //请求地址
	path := url.Path
	query := url.RawQuery
	fullPath := path
	if query != "" {
		fullPath = path + "?" + query
	}
	// 获取客户端IP
	clientIP := ipUtil.GetClientIp(r.GetCtx())
	OperLocation := ipUtil.GetCityByIp(clientIP)

	// 获取请求参数
	var params string
	if r.Method == "GET" {
		params = query
	} else {
		// 对于非GET请求，尝试获取请求体
		params = string(r.GetBody())
	}
	// 限制参数长度，避免日志过大
	if len(params) > 2000 {
		params = params[:2000] + "..."
	}
	data := &mymodel.OperLog{
		Title:         "",
		BusinessType:  0,
		Method:        url.Path,
		RequestMethod: r.Method,
		OperatorType:  1,
		OperName:      userInfo.Username,
		DeptId:        int64(userInfo.DeptId),
		OperUrl:       fullPath,
		OperIp:        clientIP,
		OperLocation:  OperLocation,
		OperParam:     params,
	}
	err = s.Invoke(r.GetCtx(), data)
	if err != nil {
		glog.Info(r.GetCtx(), err)
		return
	}
	return
}

func (s *sOplog) Invoke(ctx context.Context, data *mymodel.OperLog) (err error) {
    // 复制数据，避免闭包引用问题
    logData := *data
    
    // 使用context.Background()创建独立的context，避免原始请求context被取消时影响日志写入
    err = s.Pool.Add(context.Background(), func(ctx context.Context) {
        //写入日志数据
        err := s.Add(ctx, &logData)
        if err != nil {
            glog.Error(ctx, "写入操作日志失败:", err)
            return
        }
    })
    if err != nil {
        glog.Error(ctx, "添加日志任务到协程池失败:", err)
        return
    }
    return
}
